from rest_framework import generics
from home.models import AxfUser
from user.user_serializers import UserSerializer,UserRegisterSerializer,UserLoginSerializer
from user.util import token_confirm
from rest_framework.response import Response

# Create your views here.


class UserShowView(generics.GenericAPIView):
    '''
    get:
    获取我的页用户数据
    '''
    queryset = AxfUser.objects.all()
    serializer_class = UserSerializer

    def get(self,request):
        token=request.query_params.get('token') # 获取GET请求传入的token的值
        try:
            id=token_confirm.check_activate_token(token) # 校验token
        except Exception as e:
            print(e) # token有三部分，以.分割，访问时若没token，会给token传null，校验时会找.，但null中无.，所以打印No b'.' found in value
            return Response({
                'code':401,
                'msg':'token错误，请重新登录',
                'data':{}
            })
        try:
           user=AxfUser.objects.get(pk=id) # token正确，获取到了id，再去数据库查询该用户
        except Exception as e: # 例如token正确后，此时该用户刚好被从数据库中删除
            print(e)
            return Response({
                'code':404,
                'msg':'该用户不存在',
                'data':{}
            })
        serializer=UserSerializer(instance=user) # 序列化。id是唯一的，查到的用户是唯一的，所以不用加many=True
        return Response({
            'code':200,
            'msg':'请求成功',
            'data':{'user_info':serializer.data}
        })


class UserRegisterView(generics.GenericAPIView):
    '''
    post:
    我的页注册
    '''
    queryset = AxfUser.objects.all()
    serializer_class = UserRegisterSerializer

    def post(self,request):
        serializer=self.get_serializer(data=request.data) # 反序列化，将字典转为模型对象。反序列化时将要被反序列化的数据传给data参数。djangorestframework的request.data中含有各种方法的请求数据，不像request.POST那样只有POST的数据。
        if serializer.is_valid(): # 验证前端传来的数据是否完整
            # print(serializer.validated_data) # 通过验证的数据
            user=serializer.save() # 将反序列化后的数据存入数据库。save()方法调用序列化类的父类Serializer的父类BaseSerializer的save()方法，创建新对象时父类BaseSerializer的save()方法调用同类的create()方法，user/user_serializers.py中UserRegisterSerializer类中重写了create()方法，所以这里的save()方法调用重写后的create()方法
            return Response({ # 注册成功
                'code':200,
                'msg':'请求成功',
                'data':{'user_id':user.id}
            })
        else:
            return Response({ # 注册失败
                'code':400,
                'msg':'请求参数校验失败',
                'data':{'info':serializer.errors} # POST、PUT、PATCH出错时返回400状态码。errors属性里是错误信息
            })


class UserLoginView(generics.CreateAPIView):
    '''
    post:
    我的页登录，未登录时点我的页的"未登录"。
    '''
    queryset = AxfUser.objects.all()
    serializer_class = UserLoginSerializer

    def create(self, request, *args, **kwargs): # 重写CreateAPIView类的post()方法的返回值中的create()方法。这里方法名不用写post()方法，因它调用create()方法，所以可以直接重写create()方法
        serializer = self.get_serializer(data=request.data)
        if serializer.is_valid():
            username=serializer.data.get('u_username') # serializer.data返回ReturnDict类型，所以也可以用中括号获取值，即serializer.data['u_username']。若用serializer.validated_data，是下两行的三种方法
            # username=[value for key,value in serializer.validated_data.items() if 'u_username'==key][0] # serializer.validated_data返回OrderedDict类型，字典的items()方法返回可遍历的键和值，将键为u_username的值放入列表，列表中只有一个元素，再取第一个元素
            # username=serializer.validated_data.get('u_username');username=serializer.validated_data['u_username']
            user=AxfUser.objects.filter(u_username=username).first()
            token=token_confirm.generate_activate_token(user.id) # 生成token。djangorestframework开发，客户端不一定是浏览器，不是浏览器时无法使用cookie和session，只能使用token
            return Response({ # 登录成功
                'code':200,
                'msg':'请求成功',
                'data':{'user_id':user.id,'token':token}
            })
        else:
            print('错误：',serializer.errors)
            return Response({ # 登录失败
                'code':401,
                'msg':'请求参数校验失败',
                'data':{'error':serializer.errors,'token':None} # vue中写的会获取token，所以登录失败时也要返回token，否则前端报错
            })
